package com.baogu.factoryjob.job.handler;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baogu.factoryjob.service.BaoGuDataService;
import com.baogu.factoryjob.service.ControllerStatusService;
import com.baogu.factoryjob.service.TerminalWarningService;
import com.baogu.factoryjob.service.remote.ControllerStatusRemoteService;
import com.baogu.factoryjob.util.DateUtils;
import com.baogu.model.common.HttpResult;
import com.baogu.model.database.ControllerStatus;
import com.baogu.model.database.where.ControllerStatusWhere;
import com.baogu.model.job.where.ErrorJobWhere;
import com.baogu.model.job.where.TerminalWarningWhere;
import com.github.pagehelper.PageInfo;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

@Service @DisallowConcurrentExecution
public class ControllerStatusJobHand implements Job {

    private final static int type = 1;


    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        PageInfo<ControllerStatus> pageInfo = null;
        Integer initNum = _initNum,
                pageSize = _pageSize;
        Map<String,ControllerStatus> map = null;
        do {
            HttpResult httpResult = controllerStatusRemoteService.allList(initNum,pageSize);
            JSONObject jsonObject = (JSONObject) httpResult.getData();
            pageInfo = jsonObject.toJavaObject(PageInfo.class);
            if(null == httpResult.getCode()|| StringUtils.isEmpty(httpResult.getCode())){
                return;
            }
            if(pageInfo == null){
                //远程调用为空
                return;
            }
            if(pageInfo.getTotal()==0){
                //查询数据为空
                return;
            }
            if (map == null){
                map = getControllerStatus();
            }
            List<ControllerStatus> list = pageInfo.getList();
            saveData(list,map);
            initNum+=1;
        }while (pageInfo != null && pageInfo.isHasNextPage());
        /*
        ControllerStatusWhere where = new ControllerStatusWhere();
        ControllerStatus status = new ControllerStatus();
        controllerStatusService.updateByWhere(status,where);
        controllerStatusService.deleteByWhere(where);
        controllerStatusService.updateByWhere(status,where);
        */
    }

    /**
     * 获取当前控制器状态表中所有的数据
     * @return
     */
    private Map<String,ControllerStatus> getControllerStatus(){
        Map<String,ControllerStatus> map = new HashMap<>();
        ControllerStatusWhere where = new ControllerStatusWhere();
        List<ControllerStatus> list = controllerStatusService.getAllList(where);
        if(list == null || list.size() == 0){
            return null;
        }
        for (ControllerStatus controllerStatus:list){
            map.put(controllerStatus.getControllerid(),controllerStatus);
        }
        return map;
    }

    /**
     * 保存控制器状态
     * @param list
     * @return
     */
    private SaveResultData saveData(List list,Map<String,ControllerStatus> map) {
        SaveResultData saveResultData = new SaveResultData();
        try {
            for (Object object : list) {
                JSONObject jsonObject = (JSONObject) object;
                ControllerStatus cs = jsonObject.toJavaObject(ControllerStatus.class);
                if(cs == null){
                    continue;

                }
                if (null == map || null == map.get(cs.getControllerid())){
                    controllerStatusService.saveData(cs);
                }
                else if (null != map.get(cs.getControllerid()).getUpdatetime() && null != cs.getUpdatetime() && map.get(cs.getControllerid()).getUpdatetime().getTime() < cs.getUpdatetime().getTime()){
                    ControllerStatusWhere where = new ControllerStatusWhere();
                    where.setControllerid(cs.getControllerid());
                    controllerStatusService.updateByWhere(cs,where);
                    setControllerStatus(cs);
                }
                else
                {
                    continue;
                }
                setControllerStatus(cs);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            //保存错误
            saveResultData.failCount--;
        }
        return saveResultData;
    }

    private void setControllerStatus(ControllerStatus controllerStatus){
        com.baogu.model.job.ControllerStatus cs = new com.baogu.model.job.ControllerStatus();
        cs.setControllerId(controllerStatus.getControllerid());
        cs.setCollectionPointStatus(controllerStatus.getStatus()!=null?controllerStatus.getStatus().toString():null);
        baoGuDataService.setControllerStatus(cs);
        if(null != controllerStatus.getStatus()){
            TerminalWarningWhere terminalCollection = new TerminalWarningWhere();
            terminalCollection.setControllerId(controllerStatus.getControllerid());
            terminalWarningService.delLast(terminalCollection);
        }
    }

    private void saveErrorJob(String data,String msg,String version){
        ErrorJobWhere where = new ErrorJobWhere();
        where.setCreateDate(DateUtils.now());
        where.setUpdateDate(DateUtils.now());
        where.setMsg(msg);
        where.setType(type);
        where.setState(0);
        where.setVersion(version);
        where.setData(data);
        baoGuDataService.saveErrorJob(where);
    }

    @Autowired
    ControllerStatusRemoteService controllerStatusRemoteService;
    @Autowired
    ControllerStatusService controllerStatusService;
    @Autowired
    BaoGuDataService baoGuDataService;
    @Autowired
    TerminalWarningService terminalWarningService;

    @Value("${page.initNum}")
    private Integer _initNum;
    @Value("${page.pageSize}")
    private Integer _pageSize;

    private class SaveResultData{
        public Integer sussceCount = 0;
        public Integer failCount = 0;
    }
}
